from __future__ import generators
import Queue
import os
import sys
import threading
import time
import win32con
import win32file

ACTIONS = {
    1 : "Created",
    2 : "Deleted",
    3 : "Updated",
    4 : "Renamed to something",
    5 : "Renamed from something"
}

def watch_path(path_to_watch, include_subdirectories=False):
    FILE_LIST_DIRECTORY = 0x0001
    hDir = win32file.CreateFile(
        path_to_watch,
        FILE_LIST_DIRECTORY,
        win32con.FILE_SHARE_READ | 
         win32con.FILE_SHARE_WRITE |
         win32con.FILE_SHARE_DELETE,
        None,
        win32con.OPEN_EXISTING,
        win32con.FILE_FLAG_BACKUP_SEMANTICS,
        None
    )
    while True:
        results = win32file.ReadDirectoryChangesW(
            hDir,
            8192,
            include_subdirectories,
            win32con.FILE_NOTIFY_CHANGE_FILE_NAME | 
             win32con.FILE_NOTIFY_CHANGE_DIR_NAME | 
             win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES | 
             win32con.FILE_NOTIFY_CHANGE_SIZE | 
             win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |  
             win32con.FILE_NOTIFY_CHANGE_SECURITY,
            None,
            None
        )
        for action, file in results:
            full_filename = os.path.join(path_to_watch, file)
            if not os.path.exists(full_filename):
                file_type = "<deleted>"
            elif os.path.isdir(full_filename):
                file_type = 'folder'
            else:
                file_type = 'file'
            
            action = ACTIONS.get(action, 'Unknown')
            yield file_type, path_to_watch, file, action

class Watcher(threading.Thread):

    def __init__(self, path_to_watch, results_queue, **kwds):
        threading.Thread.__init__(self, **kwds)
        self.setDaemon(1)
        self.path_to_watch = path_to_watch
        self.results_queue = results_queue

    def run(self):
        for result in watch_path(self.path_to_watch, True):
            self.results_queue.put(result)

if __name__ == '__main__':
    PATH_TO_WATCH = ["."]
    
    try: path_to_watch = sys.argv[1].split(",") or PATH_TO_WATCH
    except: path_to_watch = PATH_TO_WATCH
    path_to_watch = [os.path.abspath(p) for p in path_to_watch]

    print "Watching %s at %s" %(", ".join(path_to_watch), time.asctime())
    files_changed = Queue.Queue()
    
    for p in path_to_watch:
        Watcher(p, files_changed).start()

    while 1:
        try:
            print files_changed.get(timeout=1)
        except Queue.Empty: pass

